package org.goodsmanager.service.impl;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.goodsmanager.entity.OperationLog;
import org.goodsmanager.mapper.OperationLogMapper;
import org.goodsmanager.service.OperationLogService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.UUID;

/**
 * 操作日志服务实现类
 *
 * @author Goods Manager System
 * @version 1.0.0
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class OperationLogServiceImpl implements OperationLogService {

    private final OperationLogMapper operationLogMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void recordLog(OperationLog operationLog) {
        try {
            // 设置ID和创建时间
            if (operationLog.getId() == null || operationLog.getId().isEmpty()) {
                operationLog.setId(UUID.randomUUID().toString().replace("-", ""));
            }
            if (operationLog.getCreatedAt() == null) {
                operationLog.setCreatedAt(LocalDateTime.now());
            }
            
            // 保存到数据库
            operationLogMapper.insert(operationLog);
            log.debug("操作日志记录成功: {}", operationLog.getId());
        } catch (Exception e) {
            log.error("操作日志记录失败", e);
            // 日志记录失败不应该影响主业务流程，所以这里只记录错误，不抛出异常
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteLogById(String id) {
        try {
            int result = operationLogMapper.deleteById(id);
            return result > 0;
        } catch (Exception e) {
            log.error("删除操作日志失败, ID: {}", id, e);
            throw new RuntimeException("删除操作日志失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchDeleteLogs(List<String> ids) {
        try {
            if (ids == null || ids.isEmpty()) {
                return true;
            }
            int result = operationLogMapper.batchDelete(ids);
            return result > 0;
        } catch (Exception e) {
            log.error("批量删除操作日志失败", e);
            throw new RuntimeException("批量删除操作日志失败", e);
        }
    }

    @Override
    public OperationLog getLogById(String id) {
        try {
            return operationLogMapper.selectById(id);
        } catch (Exception e) {
            log.error("查询操作日志失败, ID: {}", id, e);
            throw new RuntimeException("查询操作日志失败", e);
        }
    }

    @Override
    public List<OperationLog> getLogsByPage(int pageNum, int pageSize, String userId, String operationType, 
                                           String module, String status, LocalDateTime startTime, 
                                           LocalDateTime endTime, String keyword) {
        try {
            int offset = (pageNum - 1) * pageSize;
            return operationLogMapper.selectByPage(offset, pageSize, userId, operationType, 
                                                 module, status, startTime, endTime, keyword);
        } catch (Exception e) {
            log.error("分页查询操作日志失败", e);
            throw new RuntimeException("分页查询操作日志失败", e);
        }
    }

    @Override
    public int getLogCount(String userId, String operationType, String module, String status, 
                          LocalDateTime startTime, LocalDateTime endTime, String keyword) {
        try {
            return operationLogMapper.selectCount(userId, operationType, module, status, 
                                                startTime, endTime, keyword);
        } catch (Exception e) {
            log.error("查询操作日志总数失败", e);
            throw new RuntimeException("查询操作日志总数失败", e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean cleanLogsBefore(int days) {
        try {
            if (days <= 0) {
                return true;
            }
            LocalDateTime beforeTime = LocalDateTime.now().minusDays(days);
            int result = operationLogMapper.deleteBefore(beforeTime);
            log.info("清理了 {} 天前的 {} 条操作日志", days, result);
            return true;
        } catch (Exception e) {
            log.error("清理操作日志失败", e);
            throw new RuntimeException("清理操作日志失败", e);
        }
    }

    @Override
    public List<Map<String, Object>> countByOperationType(LocalDateTime startTime, LocalDateTime endTime) {
        try {
            return operationLogMapper.countByOperationType(startTime, endTime);
        } catch (Exception e) {
            log.error("统计各类型操作数量失败", e);
            throw new RuntimeException("统计各类型操作数量失败", e);
        }
    }

    @Override
    public List<Map<String, Object>> countByModule(LocalDateTime startTime, LocalDateTime endTime) {
        try {
            return operationLogMapper.countByModule(startTime, endTime);
        } catch (Exception e) {
            log.error("统计各模块操作数量失败", e);
            throw new RuntimeException("统计各模块操作数量失败", e);
        }
    }

    @Override
    public List<Map<String, Object>> countByUser(LocalDateTime startTime, LocalDateTime endTime, int limit) {
        try {
            return operationLogMapper.countByUser(startTime, endTime, limit);
        } catch (Exception e) {
            log.error("统计用户操作数量失败", e);
            throw new RuntimeException("统计用户操作数量失败", e);
        }
    }

    @Override
    public List<OperationLog> exportLogs(String userId, String operationType, String module, String status, 
                                        LocalDateTime startTime, LocalDateTime endTime, String keyword) {
        try {
            // 导出不分页，获取所有符合条件的记录
            return operationLogMapper.selectByPage(0, 100000, userId, operationType, 
                                                 module, status, startTime, endTime, keyword);
        } catch (Exception e) {
            log.error("导出操作日志失败", e);
            throw new RuntimeException("导出操作日志失败", e);
        }
    }
}